<?php
declare(strict_types=1);

namespace App\Service;

use App\Constants\SettleAccessType;
use App\Constants\StrStatus;
use App\Constants\XZXResponseCode;
use App\Exception\XZXValidationException;
use App\Model\Dao\EventOrderDao;
use App\Model\Dao\MchAccountAccessDetailDao;
use App\Model\Dao\MchAccountDao;
use App\Model\Dao\MchConfigDao;
use App\Model\Enum\CommonReviewStatusEnum;
use App\Model\Enum\EventOrderAccountTypeEnum;
use App\Model\Enum\EventOrderTypeEnum;
use App\Model\Enum\OrderHandleStatusEnum;
use App\Utils\ArrayUtils;
use App\Utils\CustomUtils;
use App\Utils\DateUtils;
use App\Utils\NumberUtils;
use Hyperf\Di\Annotation\Inject;


class EventOrderService
{
    /**
     * @Inject()
     * @var EventOrderDao
     */
    private $EventOrderDao;

    /**
     * @Inject()
     * @var MchAccountDao
     */
    private $MchAccountDao;

    /**
     * @Inject()
     * @var MchConfigDao
     */
    private $MchConfigDao;

    /**
     * @Inject()
     * @var SettleService
     */
    private $SettleService;

    public function get($param)
    {
        $result = $this->EventOrderDao->get($param['id']);
        if (!$result) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::DATA_NOT_FOUND));
        }

        if($param['source'] == 2 && !$param['isSuperRole']){
            if(!in_array($result['mchId'],$param['mchIdList'])){
                throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::NO_PERMISSION_TO_OPERATE));
            }
        }

        if($param['source'] == 1){
            if($result['mchId'] != $param['mchId']){
                throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::NO_PERMISSION_TO_OPERATE));
            }
        }

        (isset($result['createTime']) && !empty($result['createTime'])) && $result['createTime'] = DateUtils::getDateTime($result['createTime']);
        (isset($result['reviewTime']) && !empty($result['reviewTime'])) && $result['reviewTime'] = DateUtils::getDateTime($result['reviewTime']);
        (isset($result['reReviewTime']) && !empty($result['reReviewTime'])) && $result['reReviewTime'] = DateUtils::getDateTime($result['reReviewTime']);
        $result['strHandleStatus'] = OrderHandleStatusEnum::getLabel($result['handleStatus']);
        $result['strReviewStatus'] = CommonReviewStatusEnum::getLabel($result['reviewStatus']);
        $result['strReReviewStatus'] = CommonReviewStatusEnum::getLabel($result['reReviewStatus']);
        $result['strAccountType'] = EventOrderAccountTypeEnum::getLabel($result['accountType']);

        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE,XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE),$result);
    }

    public function add($param)
    {
        $mchConfig = $this->MchConfigDao->getByMchId($param['mchId']);
        if (!$mchConfig) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::NOT_SET_MCH_CONFIG));
        }
        $this->checkParam($param);

        $data =  [
            "id"            => CustomUtils::createUUID(),
            "mchId"         => $param['mchId'],
            "mchNo"         => $param['mchNo'],
            "eventOrderNo"  => CustomUtils::createTradeNo('event'),
            "accountType"   => $param['type'] == 8004 ? 4 : 1, // 解冻就是操作事件冻结账户， 冻结扣款充值都是可提现账户
            "currency"      => $mchConfig['settleCurrency'],
            "amount"        => $param['amount'],
            "type"          => $param['type'],
            "createBy"      => $param['createBy'],
            'createTime'    => time(),
            'createRemark'  => $param['createRemark'],
        ];

        try {
            $this->EventOrderDao->insert($data);
        } catch (\Throwable $th) {
            CustomUtils::xzxDebug($th->getMessage());
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::ADD_FAIL));
        }

        // 写队列，事件单结算
        $this->SettleService->addMq($data['mchId'], [
            "accessType"    => SettleAccessType::ACCESS_TYPE_EVENT_ORDER_FROZEN,
            "eventOrderId"  => $data['id'],
            "handleStatus"  => 0
        ]);

        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE,XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE),CustomUtils::xzxEmptyObject());
    }

    private function checkParam($param) {
        // 如果是解冻的，需要判断一下，账户余额是否足够
        if ($param['type'] == 8004) {
            $mchAccount = $this->MchAccountDao->getWhere(['mchId' => $param['mchId']]);
            if ($param['amount'] > $mchAccount['eventFrozenAmount']) {
                throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::NOT_ENOUGH_FROZEN_AMOUNT));
            }
        }
    }

    public function list(array $param)
    {

        $limit = $param['limit'];
        $page = $param['page'];

        $total = $this->EventOrderDao->getCount($param);
        $list = $this->EventOrderDao->getList($param, $page, $limit);

        foreach ($list as $k => $v) {
            (isset($v['createTime']) && !empty($v['createTime'])) && $v['createTime'] = DateUtils::getDateTime($v['createTime']);
            (isset($v['reviewTime']) && !empty($v['reviewTime'])) && $v['reviewTime'] = DateUtils::getDateTime($v['reviewTime']);
            (isset($v['reReviewTime']) && !empty($v['reReviewTime'])) && $v['reReviewTime'] = DateUtils::getDateTime($v['reReviewTime']);
            $v['strType'] = EventOrderTypeEnum::getLabel($v['type']);
            $v['strHandleStatus'] = OrderHandleStatusEnum::getLabel($v['handleStatus']);
            $v['strReviewStatus'] = CommonReviewStatusEnum::getLabel($v['reviewStatus']);
            $v['strReReviewStatus'] = CommonReviewStatusEnum::getLabel($v['reReviewStatus']);
            if ($param['source'] == 1) {
                // 给商户看的
                $v['strAccountType'] = EventOrderAccountTypeEnum::getLabel($v['accountType'] == 1 ? 101 : 102);
            } else {
                // 给平台看的
                $v['strAccountType'] = EventOrderAccountTypeEnum::getLabel($v['accountType']);
            }
            $v['floatAmount'] = NumberUtils::centToYuan($v['amount']);
            $list[$k] = $v;
        }

        $data = array(
            'total' => $total,
            'list' => $list
        );

        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE,XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE),$data);
    }

}
